import { IGetBrowserType, IGetType, IIsEmptyObj, IIsMobile, IIsPC, IIsPrimitive, IIsQQBrowser, IIsString, IIsStrNumber, IMerge } from "./types";
/**
 * 将对象转换为字符串形式 
 * @param obj 
 * @returns string
 */
export function formattObjectToString(obj: Object, join?: string): string {
    return Object.entries(obj)
        .map(([key, value]) => `${key}: ${value}`)
        .join(join || ' ');
}
/**
 * 扁平化数组对象
 * @param data:Array<object>
 * @param flatProp:string
 * @returns Array<any>
 */
export function flatArrayObject(data: [], flatProp: string): Array<any> {
    const result = [];
    data.forEach((item: Object) => {
        // 判断item中是否存在flatProp属性，且数组长度大于0
        if (item.hasOwnProperty(flatProp) && item[flatProp].length > 0) {
            result.push(...flatArrayObject(item[flatProp], flatProp));
        }
        result.push(item);
    });
    return result;
}

export function createBufferUrl(buffer: ArrayBuffer, opts: any): string {
    if (!buffer || !opts || JSON.stringify(opts) === '{}') return;
    const blob = new Blob([buffer], opts);
    return URL.createObjectURL(blob);
}

/**
 * 在对象指定路径下设置属性值，若路径不存在则创建相应的属性及其父级属性如果不存在
 * @param {object} state - 需要操作的对象
 * @param {string} path - 属性名的路径，形如："parent.child.grandson"
 * @param {*} value - 要设定的属性值
 */
export function setState(state: any, path: string, value: any) {
    let propArr: string[];
    if (path.indexOf('.') > -1) {
        propArr = path.split('.');
    } else {
        propArr = [path];
    }
    let i = 0;

    while (i < propArr.length - 1) {
        const prop = propArr[i];

        if (!state.hasOwnProperty(prop)) {
            // 当前层级下，目标属性未定义，需要创建新的对象或数组
            const nextProp = propArr[i + 1];
            state[prop] = isNaN(parseInt(nextProp)) ? {} : [];
        }

        state = state[prop];
        i++;
    }

    state[propArr[i]] = value;
}
/**
* 在对象指定路径下获取属性的值
* @param {object} state - 需要操作的对象
* @param {string} path - 属性名的路径，形如："parent.child.grandson"
* @returns {*} - 返回属性值
*/
export function getState(state: any, path: string) {
    const props = path.split('.');
    let currentProp = Object.assign({}, state);
    for (const prop of props) {
        if (!currentProp || !currentProp.hasOwnProperty(prop)) {
            return undefined;
        }
        currentProp = currentProp[prop];
    }
    return currentProp;
}

export function buildElTreeData(fileTree) {
    const treeData = [];
    treeData.push({
        id: fileTree.id,
        name: fileTree.name,
        extname: fileTree.extname || '',
        path: fileTree.path,
        type: fileTree.type,
        children: [],
    });
    const loop = (data, children) => {
        if (!data || data.length === 0) {
            return;
        }
        data.forEach(item => {
            const obj = {
                id: item.id,
                name: item.name,
                path: item.path,
                extname: item.extname || '',
                type: item.type,
                children: []
            };
            if (item.children && item.children.length > 0) {
                loop(item.children, obj.children);
            }
            children.push(obj);
        });
    };
    loop(fileTree.children, treeData[0].children);
    return treeData;
}

// 获取当前页面的性能信息
export function getPerformance(window: Window) {
    const { performance } = window;
    if (!performance) {
        console.log('浏览器不支持 performance 接口');
        return;
    }
    const time = performance.timing;
    const loadTime = time.loadEventEnd - time.navigationStart; // 计算加载时间
    console.log(`整个项目加载时间为 ${loadTime} 毫秒`);
    const dnsTime = time.domainLookupEnd - time.domainLookupStart; // DNS查询时间
    console.log(`DNS查询时间为 ${dnsTime} 毫秒`);
    const tcpTime = time.connectEnd - time.connectStart; // TCP建立时间
    console.log(`TCP建立时间为 ${tcpTime} 毫秒`);
    const requestTime = time.responseEnd - time.requestStart; // request请求耗时
    console.log(`request请求耗时为 ${requestTime} 毫秒`);
    const parseDOMTime = time.domComplete - time.domInteractive; // 解析dom树耗时
    console.log(`解析dom树耗时为 ${parseDOMTime} 毫秒`);
    const whiteScreenTime = time.domInteractive - time.fetchStart; // 白屏时间
    console.log(`白屏时间为 ${whiteScreenTime} 毫秒`);
    const domReadyTime = time.domContentLoadedEventEnd - time.fetchStart; // domready时间
    console.log(`domready时间为 ${domReadyTime} 毫秒`);
    const onloadTime = time.loadEventEnd - time.navigationStart >= 0 ? time.loadEventEnd - time.navigationStart : undefined; // onload时间
    console.log(`onload时间为 ${onloadTime} 毫秒`);
}

// 合并对象
export const merge: IMerge = (target, ...args) => {
    args.forEach(arg => Object.assign(target, arg));
    return target;
}

// 获取类型函数
export const getType: IGetType = (obj) => {
    const type = typeof obj;
    if (type !== 'object') {  // 如果为基础类型就返回
        return type;
    }
    return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1');
}

export const isStrNumber: IIsStrNumber = (num) => {
    return /[0-9]/g.test(num);
}
export const isString: IIsString = (str) => {
    return typeof str === 'string';
}
export const isEmptyObj: IIsEmptyObj = (obj) => {
    return JSON.stringify(obj) === "{}"
}
/**
 * 是否为基本类型
 * @param obj 
 * @returns {boolean}
 */
export const isPrimitive: IIsPrimitive = (obj) => {
    return (
        typeof obj === "string" ||
        typeof obj === "number" ||
        typeof obj === "boolean" ||
        typeof obj === "symbol" ||
        typeof obj === "bigint"
    );
}

/**
 * 是否为移动端
 * @param ua 传入navigator.userAgent属性
 * @returns {boolean}
 */
export const isMobile: IIsMobile = (ua) => {
    return /android|webos|iphone|ipod|balckberry/i.test(ua)
}

/**
 * 是否为PC端
 * @param ua 传入navigator.userAgent属性
 * @returns {boolean}
 */
export const isPC: IIsPC = (ua) => {
    const Agents = ["Android", "iPhone",
        "SymbianOS", "Windows Phone",
        "iPad", "iPod"];
    let flag = true;
    for (let v = 0; v < Agents.length; v++) {
        if (ua.indexOf(Agents[v]) > 0) {
            flag = false;
            break;
        }
    }
    return flag;
}

/**
 * 是否为QQ浏览器
 * @param ua 传入navigator.userAgent属性
 * @returns {boolean}
 */
export const isQQBrowser: IIsQQBrowser = (ua) => {
    return !!ua.match(/mqqbrowser|qzone|qqbrowser|qbwebviewtype/i)
}

/**
 * 获取浏览器的类型
 * @param ua 传入navigator.userAgent属性
 * @returns {string}
 */
export const getBrowserType: IGetBrowserType = (ua) => {
    const kUserAgent = {
        Opera: 'Opera',
        Firefox: 'Firefox',
        Chrome: 'Chrome',
        Safari: 'Safari',
        IE: 'IE',
        QQ: 'QQBrowser'
    };
    // })
    if (ua.indexOf('Opera') > -1) {
        // 判断是否Opera浏览器
        return kUserAgent.Opera;
    }
    if (ua.indexOf('Firefox') > -1) {
        // 判断是否Firefox浏览器
        return kUserAgent.Firefox;
    }
    if (ua.indexOf('QQBrowser') > -1) {
        return kUserAgent.QQ
    }
    if (ua.indexOf('Chrome') > -1) {
        // 判断是否为谷歌浏览器
        return kUserAgent.Chrome;
    }
    if (ua.indexOf('Safari') > -1) {
        // 判断是否Safari浏览器
        return kUserAgent.Safari;
    }

    if (
        ua.indexOf('compatible') > -1 &&
        ua.indexOf('MSIE') > -1 &&
        ua.indexOf('Opera') > -1
    ) {
        // 判断是否IE浏览器
        return kUserAgent.IE;
    }
    return '';
}